home *** CD-ROM | disk | FTP | other *** search
/ Mac100% 1998 November / MAC100-1998-11.ISO.7z / MAC100-1998-11.ISO / オンラインソフト定点観測 / ユーティリティ / Mops 3.2.sea / Mops 3.2 / Mops ƒ / Base < prev    next >
Text File  |  1998-06-03  |  15KB  |  592 lines

  1. ¥ Sept 92 mrh    New words etc. moving closer to ANSI standard
  2. ¥ Jul  93 mrh    Select{  removed - replaced by Select[ in caseMod
  3.  
  4. cr .( loading Base...)
  5.  
  6. false    value    ECHO?        ¥ echo load to screen?
  7.  
  8.     0    value    ACTW
  9.                        ¥ Indentifies any active Mops window which
  10.                     ¥ should be idled.  Will be set zero if we have, say,
  11.                     ¥ a dialog as the front window, but NOT if we're
  12.                     ¥ switched into the background.
  13.  
  14.     0    value    emb_obj_offs
  15.                     ¥ Saves the offs returned by <findM>, which we need
  16.                     ¥  for inline binding.  We define it back here
  17.                     ¥  since it needs to be saved and restored over
  18.                     ¥  anything which types to the Mops window (which
  19.                     ¥  also causes <findM> to be called).  In particular,
  20.                     ¥  EVALUATE and FRefill with echoing on, type to
  21.                     ¥  the Mops window.
  22.  
  23.  
  24. ¥ (* ... *) defines a multi-line comment, which can be very useful.  Many
  25. ¥ Pascal compilers use these symbols - I thought it better not to use
  26. ¥ the C-style /* ... */  since */ already has a meaning.
  27. ¥ A useful improvement to the typical Pascal implementation is to keep a
  28. ¥ level count so that this kind of comment can be nested.
  29.  
  30. : (*
  31.     1                            ¥ initial level count
  32.     BEGIN
  33.         Mword  count  2dup
  34.         " (*"  s=
  35.         IF    2drop  1 +            ¥ increment level count
  36.         ELSE
  37.             " *)"  s=
  38.             IF  1 -                ¥ decrement level count
  39.                 ?dup  0EXIT        ¥ and if zero, we're done
  40.             THEN
  41.         THEN
  42.     AGAIN  ;        immediate
  43.  
  44.  
  45. ¥ We redefine a few useful words to take advantage of our optimization.
  46.  
  47. : 1+    state IF 1 postpone literal  postpone +  ELSE  1 +  THEN  ;    immediate
  48. : 2+    state IF 2 postpone literal  postpone +  ELSE  2 +  THEN  ;    immediate
  49. : 3+    state IF 3 postpone literal  postpone +  ELSE  3 +  THEN  ; immediate
  50. : 4+    state IF 4 postpone literal  postpone +  ELSE  4 +  THEN  ; immediate
  51.  
  52. : 1-    state IF 1 postpone literal  postpone -  ELSE  1 -  THEN  ;    immediate
  53. : 2-    state IF 2 postpone literal  postpone -  ELSE  2 -  THEN  ;    immediate
  54. : 3-    state IF 3 postpone literal  postpone -  ELSE  3 -  THEN  ;    immediate
  55. : 4-    state IF 4 postpone literal  postpone -  ELSE  4 -  THEN  ;    immediate
  56.  
  57. : 2*    state IF 1 postpone literal  postpone << ELSE  1 << THEN  ;    immediate
  58. : 2/    state IF 1 postpone literal  postpone a>> ELSE 1 a>> THEN ;    immediate
  59. : 4*    state IF 2 postpone literal  postpone << ELSE  2 << THEN  ;    immediate
  60. : 4/    state IF 2 postpone literal  postpone a>> ELSE 2 a>> THEN ;    immediate
  61.  
  62. ¥ ANSI words
  63.  
  64. : CELL+    state IF  postpone 4+  ELSE  4 +  THEN  ;    immediate
  65. : CELL-    state IF  postpone 4-  ELSE  4 -  THEN  ;    immediate
  66. : CELLS    state IF  2 postpone literal  postpone <<  ELSE    2 <<  THEN  ;  immediate
  67. : CHAR+    state IF  postpone 1+  ELSE  1 +  THEN  ;    immediate
  68. : CHARS    ;                        immediate
  69.  
  70. 4    constant    1CELL            ¥ Not ANSI, but useful
  71.  
  72.  
  73. : RECURSE        curr-def  compile,  ;            immediate
  74.  
  75. : SAVE-INPUT
  76.     src-start  src-len  >in @  source-id  4  ;
  77.  
  78. : RESTORE-INPUT
  79.     dup 4 <>  IF  true  EXIT  THEN
  80.     drop
  81.     -> source-id  >in !  -> src-len  -> src-start  false  ;
  82.  
  83.  
  84. ¥ :NONAME is an ANSI word - the Standard defines the stack effect as:
  85. ¥  ( C:  -- colon-sys )  ( S:  -- xt )
  86. ¥ In Mops we implement the control-flow stack on the data stack, which
  87. ¥  the Standard allows, specifying that the control-flow stack items 
  88. ¥  go above the data stack items.  In this word, "colon-sys" is just a
  89. ¥  security marker (300), so we return this on top of the xt.
  90.  
  91. : :NONAME  ( -- xt 300 )
  92.     (:)  -2 w,            ¥ set up compilation, comma in colon handler
  93.     DP                    ¥ xt = cfa
  94.     300                    ¥ security marker - part of "control-sys" in the
  95.                         ¥  ANSI defn
  96. ;
  97.  
  98.  
  99. ¥        =========================
  100.  
  101. ¥ These can be useful:
  102.  
  103. : UMAX    2dup u> IF drop ELSE nip THEN  ;
  104. : UMIN    2dup u< IF drop ELSE nip THEN  ;
  105.  
  106.  
  107. ¥ .H and U.H print a number in hex, signed and unsigned respectively.
  108.  
  109. : .H    base >r  hex   .  r> -> base  ;
  110. : U.H    base >r  hex  u.  r> -> base  ;
  111.  
  112.  
  113.     0    constant    Z
  114.  
  115. : NULLOSSTR        ['] z  ;
  116.  
  117.  
  118. : @WORD        ¥ ( -- addr )  Retrieves next blank-delimited word from input stream.
  119.     bl word  ;
  120.  
  121. : LIT        ¥ ( n -- )  A state-smart version of LITERAL.  Corresponds
  122.             ¥ to LITERAL in Fig-Forth or original Neon, whereas our
  123.             ¥ present LITERAL is Forth-83/ANSI.
  124.     state  IF  postpone literal  THEN  ;        immediate
  125.  
  126. : 0,  0 ,  ;        ¥ Compiles an empty cell
  127.  
  128. : @VAL    intrp1  ;    ¥ Compiles a number from input stream
  129.  
  130.  
  131. : 'TYPE        ¥ ( -- 4bytes )   OS type literal
  132.     pad 4 bl fill  @word count 4 min
  133.     pad swap cmove  pad @  postpone lit  ;    immediate
  134.  
  135. create BUF255  256 allot        ¥ buffer for string operations
  136.  
  137. : >STR255        ¥ ( addr len addr -- addr )
  138.                 ¥ Converts a string to a Str255 at addr
  139.     dup >r  place  r>  ;
  140.  
  141. : STR255    ¥ ( -- ^buf255 )
  142.     buf255 >str255  ;
  143.  
  144.  
  145. : CHAR        @word 1+ c@  ;                ¥ ANSI - replaces ASCII
  146. : [CHAR]    @word 1+ c@  postpone literal  ;    immediate
  147.  
  148. : &            ¥ ( -- c )  A shorter state-smart version.
  149.     @word 1+ c@  postpone lit  ;        immediate
  150.  
  151.  
  152. : $        ¥ State-smart HEX literal word
  153.     base >r
  154.     hex  Mword  number  postpone lit
  155.     r> -> base  ;            immediate
  156.  
  157.  
  158. : LITW        ¥ ( n -- )
  159.     $ 3D3C w,  w,  ;
  160.  
  161.  
  162. : W        intrp1  litw  ;        immediate
  163.  
  164.  
  165. (* Trap compilation.  When we're fully native on the PowerPC this will
  166.    become totally obsolete...
  167. *)
  168.  
  169.  
  170. : SAVA5        postpone doSavA5  ;
  171.  
  172. : RSTA5
  173.     $ CD4F w,            ¥    exg    a6,a7
  174.     $ 2A5F w,  ;        ¥    move.l    (a7)+,a5
  175.  
  176. : (TRAP$)    ¥ ( trap# -- )  Compiles a call to the given trap.
  177.     SavA5  w,  RstA5  ;
  178.  
  179. : TRAP$        ¥ ( --<trap#> )
  180.     base >r
  181.     hex  intrp1  (trap$)
  182.     r> -> base  ;        immediate
  183.  
  184.  
  185. : (FDOS$)        ¥ ( trap# -- )
  186.     $ 205E w,                ¥    move.l    (a6)+,a0    ; FCB pointer
  187.     SavA5  w,  RstA5
  188.     $ 48C0 w,                ¥    ext.l    d0    ; Result
  189.     $ 2D00 w,  ;            ¥    move.l    d0,-(a6)
  190.  
  191.  
  192. : FDOS$        ¥ ( --<trap#> )
  193.     base >r
  194.     hex  intrp1  (fdos$)
  195.     r> -> base  ;        immediate
  196.  
  197.  
  198. ¥        ============ PowerPC stuff ===========
  199.  
  200. ¥ Once we're compiling PPC code, we have to keep the code and data areas
  201. ¥  distinct.  DP points to the data area, so we now add CDP pointing to
  202. ¥  the code area.
  203.  
  204.     0    value    CDP
  205.  
  206. false    value    CROSSED?        ¥ True once we've CROSSed into the PPC image.
  207.  
  208.  
  209. : code,        PPC? IF  CDP !   4 ++> CDP  ELSE  ,   THEN  ;
  210. : codeW,    PPC? IF  CDP w!  2 ++> CDP  ELSE  w,  THEN  ;
  211. : codeC,    PPC? IF  CDP c!  1 ++> CDP  ELSE  c,  THEN  ;
  212.  
  213.  
  214. : RESERVE        ¥ ( len -- )  Allot and clear.
  215.     here over erase allot  ;
  216.  
  217. : CODE_RESERVE
  218.     CDP over erase  ++> CDP  ;
  219.  
  220.  
  221. ' null  vect  PPC_HEADER
  222. ' 2drop    vect  ppc_sHdr    
  223.  
  224.  
  225. (*  - now in Files.
  226.  
  227. : MARK_FILE        ¥ ( addr len -- )
  228.                 ¥  This needs to know about the PPC, so we redefine it:
  229.     crossed?
  230.     IF    >r pad r@ cmove
  231.         bl pad r@ + c!                ¥ append a blank to the file name
  232.         pad r> 1+ ppc_sHdr            ¥ lay down the header
  233.         file-mark codeW,            ¥ with the file-mark as the "handler code"
  234.         0 code,  0 codeW,  0 code,    ¥ no dir, no log, no date
  235.     ELSE
  236.         mark_file
  237.     THEN
  238. ;
  239.  
  240. *)
  241.  
  242. ¥        ============ Resources ===========
  243.  
  244. 0  value    ResRefNum
  245.  
  246. : OpenResFile        ¥ ( addr len -- )  Opens named resource file
  247.     >r >r word0 r> r> str255
  248.     trap$ a997  i->l                ¥ call OpenResFile
  249.     dup -> ResRefNum
  250.     -1 = abort" resource file open failed"  ;
  251.  
  252. : CloseResFile        ¥ ( -- )
  253.     ResRefnum  makeint  trap$ a99a  ;
  254.  
  255.  
  256. : OPENMR            ¥ Opens the Mops system resource file if necessary.
  257.     MRopen?  ?EXIT                    ¥ Do nothing if already open
  258.     instld?  ?EXIT                    ¥ or if this is an installed application
  259.     " mops.rsrc" OpenResFile
  260.     true -> MRopen?  ;
  261.  
  262.  
  263. : GETRES    ¥ ( type resID -- handle )
  264.     0 down makeint  trap$ a9a0  ;        ¥ call GetResource
  265.  
  266.  
  267.  ¥ 01Jan96 DBH redefine so addr is safe
  268. : GETSTRING        ¥ ( resID -- addr len )  Get the string with resource ID
  269.     openMR
  270.     0 swap makeint  trap$ a9ba            ¥ call getString
  271.     dup
  272.     IF    @ count  ( addr len )
  273.         pad swap  ( addr pad len )  ¥ i.e. ( src dest len)
  274.         dup >r    ¥ save len
  275.         cmove
  276.         pad r>  ( addr len )
  277.     ELSE
  278.         0
  279.     THEN  ;
  280.  
  281.  
  282. : (TSTR)            ¥ ( id# -- )  Prints string with given resID.
  283.     getString type  ;
  284.  
  285. : X    ['] (tstr) -> tstr  ;        ¥ We can't do -> outside a defn till Args loaded
  286. x  forget x
  287.  
  288.  
  289. ¥ Our normal error action is to call DIE with an error number.  DIE calls
  290. ¥ SvErr to save the error info, then THROWs the error number.  If no error
  291. ¥ handler has been installed, or only handlers which don't want that number
  292. ¥ and re-THROW it, the default action for THROW occurs.  This calls DFLT-DIE.
  293.  
  294. : (DDIE)            ¥ ( n -- )
  295.     setFwind
  296.     +echo   0 -> (err#)        ¥ Clear error indicator from AppleEvents
  297.     dflt-err  ;                ¥ Display error info and abort
  298.  
  299. : x    ['] (ddie) -> dflt-die  ;
  300. x  forget x
  301.  
  302.  
  303. : ?ERROR        ¥ ( b -- )  Aborts and prints resource string if true.
  304.                 ¥ Usage:  ?error 999
  305.     postpone if
  306.     intrp1  ( get err# )  postpone literal   postpone die
  307.     postpone then  ;        immediate
  308.  
  309.  
  310. : TYPE#        ¥ Prints string for id# in stream
  311.     intrp1  postpone lit   postpone (tStr)  ;    immediate
  312.  
  313.  
  314. : (.RSTR)    ¥ ( -- )  print "Msg# ..." then string with given resID
  315.     ." Msg# " dup . ." : "  (tStr)  ;
  316.  
  317.  
  318. : MSG#        ¥  usage: " Msg# <number>"
  319.     intrp1  postpone lit  postpone (.rStr)  ;    immediate
  320.  
  321.  
  322. ¥ ( -- #cells)
  323.  
  324. : RDEPTH        rp0  rp@ - 4/ 2-  ;
  325.  
  326. : ?RDEPTH        rp@  sp0 20 + < ?error 116  ;    ¥ err if rtn stk about to
  327.                                                 ¥ collide with data stk
  328.  
  329. : TO_BE_WRITTEN        79 die  ;
  330.  
  331.  
  332. ¥        ========== Type checking ===========
  333.  
  334. ¥ Sometimes we want to check that a non-object parameter to a word is of a 
  335. ¥ certain type.  We give it a unique type code and use TYPCHK.
  336.  
  337. : TYPCHK    <>  ?error 179  ;
  338.  
  339.  
  340. ¥        ========== Forward definitions ===========
  341.  
  342.  
  343. : X    setfWind +echo
  344.     cr ." From " r@ .id  2 spaces  r@ .h  cr  109 die  ;
  345.  
  346.  
  347. : FORWARD
  348.     colHdr
  349.     $ 487AFFFE  ,                ¥    pea   (start of this instrn)
  350.     ['] x  here  6 allot
  351.     (patch)  ;
  352.  
  353. : :F    301
  354.     here  '  (patch)  (:)  ;
  355.  
  356. : ;F    (;)  301 ?defn  ;        immediate
  357.  
  358.  
  359. forward    BLD        ¥ Used in CLASS.  Needs to be down here so we never
  360.                 ¥ refer to it with a short branch.  Kludge?
  361.  
  362. ¥ Commonly needed error words.  These are forward defined - the main
  363. ¥ application should provide a sensible definition, with a nice friendly
  364. ¥ alert box, to tell the user in a nice friendly way that things are up
  365. ¥ the creek.
  366.  
  367. forward    NOMEM        ¥ Call when (not if!) we run out of memory.
  368.  
  369. forward    I/O_ERR        ¥ ( err# -- )  Call when there's an I/O error.
  370.  
  371. : OK?        ¥ ( rc -- )  A useful word to use after an I/O op.
  372.     ?dup  0EXIT  I/O_err  ;
  373.  
  374.  
  375. ¥        ========= :PROC and ;PROC ============
  376.  
  377. : :PROC
  378.     colHdr  here  6 allot
  379.     ['] procEntry  swap  6  aligned_move
  380.     (:)  303  ;        immediate
  381.  
  382. : ;PROC        immediate
  383.     postpone procExit  (;)
  384.     303 ?defn  ;
  385.  
  386.  
  387. ¥     ======== Various utility words needed later =========
  388.  
  389. ¥ BECOME allows restarting at a given word, with all stacks
  390. ¥ empty.  This is necessary in menu handlers and other areas
  391. ¥ that could create indefinite nesting situations.
  392.  
  393. ' quit    vect    becomeXT
  394.  
  395. : BE    sp0 sp!  rp0 rp!  becomeXT  quit  ;
  396.  
  397. : (BE)    -> becomeXT  be  ;
  398.  
  399.  
  400. : BECOME        ¥ Usage: Become newWord - compiles code to Be at runtime
  401.     state
  402.     IF        postpone [']  postpone (be)
  403.     ELSE    '  -> becomeXT  be
  404.     THEN  ;            immediate
  405.  
  406.  
  407. : DATETIME
  408.     $ 20C  @  ;
  409.  
  410.  
  411. ¥        ============ Tables, lists etc. ===============
  412.  
  413. (*    With Mops 2.5 we're trying to be consistent with the way we delimit
  414.     various kinds of lists with { ... }.  No, we're not trying to copy C,
  415.     but let's at least follow the "principle of minimum astonishment"!
  416.     Thus, with words like xts{, we'll allow a variant "xts {" where you
  417.     can put a space before the "{".  This is very easy to implement, so
  418.     why not?
  419. *)
  420.  
  421. forward  {        immediate
  422.  
  423. : GOBBLE{        ¥ gobbles a "{" which must follow as a separate word.
  424.     '  ['] {  <>  ?error 113  ;        ¥ "{" expected
  425.  
  426. : )        123 die  ;    immediate        ¥ ") read when no list is current"
  427. : (})    123 die  ;    immediate        ¥ "unmatched }"
  428.  
  429. ' (})    vect    }    immediate        ¥ } will mean different things in different
  430.                                     ¥  contexts.
  431.  
  432. : }OR)?        ¥ ( cfa -- cfa b )
  433.     dup  ['] }  =  over  ['] ) =  or  ;
  434.  
  435. (*
  436. : TABLE
  437.     <BUILDS        0 w,  here  112
  438.     DOES>        length  ;
  439.  
  440. : END_TABLE
  441.     112 ?pairs
  442.     here over -            ¥ table length (excluding length field)
  443.     swap 2- w!  ;        ¥ store in length field
  444. *)
  445.     0    value        CNT
  446.  
  447.  
  448. : (LITS)        ¥ stack compiled list of values starting at IP
  449.     w@(ip)  ( count )  dup  -> cnt
  450.     4* r> tuck +  dup >r  swap
  451.     do  i @abs  4 +loop
  452.     cnt  ;
  453.  
  454.  
  455. : XTS{            ¥ State-smart word to compile or stack a list
  456.                 ¥ of xts.  Pulls words from stream, until "}".
  457.     state IF   postpone (lits)  here  0 w,  THEN
  458.     0
  459.     BEGIN   '   }or)?
  460.     NWHILE   state IF  reloc,  else  swap  THEN  1+
  461.     REPEAT
  462.     drop   state IF  swap w!  THEN  ;        immediate
  463.  
  464. : CFAS{    postpone xts{  ;    immediate        ¥ Synonyms for compatibility
  465. : CFAS(    postpone xts{  ;    immediate
  466.  
  467. : XTS    gobble{  postpone xts{  ;        immediate
  468.  
  469.  
  470. (* SCON defines a string constant.  Usage:
  471.  
  472.     scon    <name>    "a string"
  473.  
  474.   Runtime: ( -- addr len )
  475.  
  476.   Change from Neon: the first nonblank char after the name of the SCON
  477.   becomes the delimiter.  So " can be used as usual, but anything else can
  478.   be used instead, e.g.:
  479.  
  480.      scon    <name>    /this string contains " as non-delimiter/
  481. *)
  482.  
  483. : SCON
  484.     <BUILDS        bl skip-src+
  485.                 src-start >in @ + c@  ,dlm-str
  486.     DOES>        count  ;
  487.  
  488.  
  489. ¥ CASE should be used for non-contiguous or dynamically computed values.
  490. ¥ This is a modified Eaker/Duncan model.
  491. ¥ Our optimization strategy gives quite good code.
  492.  
  493. : CASE        ?comp  302  ;        immediate
  494.  
  495. : OF
  496.     postpone over  postpone =  postpone if
  497.     postpone drop  ;            immediate
  498.  
  499. : RANGEOF
  500.     postpone within?  postpone if
  501.     postpone drop  ;            immediate
  502.  
  503. : ENDOF
  504.     postpone else  ;            immediate
  505.  
  506. : ENDCASE        immediate
  507.     postpone drop
  508.     BEGIN  dup 302 =  NWHILE  >resolve  REPEAT  drop  ;
  509.  
  510. (* TYPE{ and ENUM{ (synonyms) define a Pascal/C-like enumerated type.
  511.    At this stage we don't give a name to the "type" as such, as we can't
  512.    do anything really sensible with it.  However later we can optionally
  513.    load the ENUM-TYPE class which is rather more Pascal-like.  But even
  514.    without that, the enumeration is very useful by itself.
  515. *)
  516.  
  517.     0    value    TYPECNT
  518.  
  519. ' null    vect    DO_ET        ¥ Hook for handling the ENUM-TYPE
  520.                             ¥ class when it's loaded
  521.                             
  522. : ENDLIST?        ¥ ( chr -- b )
  523.     latest n>count 1 =  down  c@ =  and
  524.     dup  IF  latest n>link  (forget)  THEN  ;
  525.  
  526.  
  527. : TYPE{
  528.     0 -> typeCnt                ¥ 1st value
  529.     BEGIN    typeCnt  constant  1 ++> typeCnt
  530.             & }  endlist?
  531.     UNTIL
  532.     do_ET  ;
  533.  
  534. : ENUM{        type{  ;            ¥ C fans might like this name better
  535. : ENUM        gobble{  type{  ;
  536.  
  537.                 ¥ note we can't allow "type { ..." since "type" has another
  538.                 ¥ meaning already.  But "enum { ..."  is OK.
  539.  
  540. enum{  InMainDic  InOtherMod  InThisMod  }        ¥ Relocatable addr types
  541.  
  542.  
  543. ¥        ========== Error diagnostics ===========
  544.  
  545. ¥ We use special values for nil handles and nil pointers.  These are
  546. ¥ odd addresses in ROM, so that if we do a word or long access we will
  547. ¥ trap, and if we write a byte it at least won't go anywhere.
  548.  
  549.  
  550. : .RTN        ¥ ( addr -- )
  551.     cr ." From  $"  .h  4 spaces  ;
  552.  
  553. : RANGE_ERR    ¥ ( index range rtn-addr -- )
  554.     dup 1+ 0=  ?error 128            ¥ Spurious range error
  555.     .rtn
  556.     dup -1 <
  557.     IF        nip  ?error 130            ¥ Not an indexed class
  558.     ELSE    ." Range: " .  ."   Index: " .
  559.             true  ?error 129
  560.     THEN  ;
  561.  
  562.  
  563. ¥ If we do software mult and div (on a 68000 which only allows a 16-bit divisor or
  564. ¥ multiplicand) we also check for overflow and call ArithErr (vector) if ovfl occurs.  
  565. ¥ The appropriate err# is on the stack already, so here we just set ArithErr to Die.
  566. ¥ This can be redirected as needed.
  567.  
  568. : X    ['] range_err -> rngErr   ['] die  -> arithErr  ;
  569.  
  570. x   forget x
  571.  
  572.  
  573. ¥        =================== MARKER =====================
  574.  
  575. ¥ On the PPC FORGET will be a bit limited, since we have a separate
  576. ¥  data area, which FORGET has no way of knowing about.  So we'll
  577. ¥  discourage FORGET, and encourage use of the standard word MARKER.
  578.  
  579. : MARKER
  580.     DP
  581.     <builds
  582.         CDP displ,  ( orig-DP ) displ,
  583.     does>
  584.         dup displace    -> CDP        4+
  585.             displace    -> DP        4+
  586.         
  587.         DP (forget)            ¥ fixes CONTEXT and LATEST
  588.         false -> echo?  false -> PPC?  false -> crossed?
  589. ;
  590.  
  591. load Args
  592.